package com.atguigu.zhxy.controller;

import com.aliyun.oss.OSS;
import com.atguigu.zhxy.pojo.Admin;
import com.atguigu.zhxy.pojo.LoginForm;
import com.atguigu.zhxy.pojo.Student;
import com.atguigu.zhxy.pojo.Teacher;
import com.atguigu.zhxy.service.AdminService;
import com.atguigu.zhxy.service.StudentService;
import com.atguigu.zhxy.service.TeacherService;
import com.atguigu.zhxy.util.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Api(tags = "系统控制器")
@RestController
@RequestMapping("/sms/system")
public class SystemController {
    @Autowired
    private AdminService adminService ;
    @Autowired
    private StudentService studentService ;
    @Autowired
    private TeacherService teacherService ;


    @Autowired
    OSS ossClient ;
    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint ;
    @Value("${spring.cloud.alicloud.oss.bucket}")
    private String bucket ;

    @ApiOperation("上传头像到服务器？如果网络中断？存储到本地服务器：阿里云服务器")
    @PostMapping("/headerImgUpload")
    public Result policy(HttpServletRequest request, @ApiParam("头像文件")@RequestPart("multipartFile") MultipartFile multipartFile){
        try {
            if(!UploadFile.isPhoto(multipartFile)){
                return Result.fail().message("图片格式不对无法上传");
            }
            //阿里云存储图片
            String host = "https://" + bucket + "." + endpoint + "/"; // host的格式为 bucketname.endpoint
            String filename = multipartFile.getOriginalFilename();
            String fileSuffix = filename.substring(filename.lastIndexOf("."), filename.length());
            log.error(fileSuffix);
            InputStream inputStream = multipartFile.getInputStream();
            String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
            String dir = format + "/"; // 用户上传文件时指定的前缀。
            ossClient.putObject(bucket, dir + uuid + fileSuffix, inputStream);
            //ossClient.shutdown();
            String urlImg = host + dir + uuid + fileSuffix;
            return Result.ok(urlImg);
        }catch (Exception e){
            //服务器保存图片
            String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
            String originalFilename = multipartFile.getOriginalFilename();
            int i = originalFilename.lastIndexOf(".");
            String newFileName = uuid.concat(originalFilename.substring(i));

            //获取编译后文件位置
            File f = new File(this.getClass().getResource("/").getPath());
            log.error(f.getPath());//D:\workspace2\zhxy\target\classes

            String portraitPath = f+"/public/upload/".concat(newFileName) ;
            try {
                multipartFile.transferTo(new File(portraitPath));
            } catch (IOException e1) {
                e1.printStackTrace();
                return Result.fail().message("图片上传超时请重试");
            }
            //响应图片的路径
            String path = "upload/".concat(newFileName) ;
            return Result.ok(path);
        }
    }

    @ApiOperation("从请求头获取Token信息")
    @GetMapping("/getInfo")//从请求头获取信息
    public Result getInfoByToken(@RequestHeader("token") String token){
        boolean expiration = JwtHelper.isExpiration(token);
        if(expiration){
            return Result.build(null, ResultCodeEnum.TOKEN_ERROR);
        }
        //从token中解析出用户名和用户类型
        Long userId = JwtHelper.getUserId(token);
        Integer userType = JwtHelper.getUserType(token);
        Map<String,Object> map = new LinkedHashMap<>() ;
        switch (userType){
            case 1:
                Admin admin = adminService.getAdminById(userId) ;
                map.put("userType",1);
                map.put("user",admin) ;
                break;
            case 2:
                Student student = studentService.getStudentById(userId) ;
                map.put("userType",2);
                map.put("user",student) ;
                break;
            case 3:
                Teacher teacher = teacherService.getTeacherById(userId) ;
                map.put("userType",3);
                map.put("user",teacher) ;
                break;
        }

        return Result.ok(map) ;
    }

    @ApiOperation("登录")
    @PostMapping("/login")
    public Result login(@ApiParam("Json的登录表单对象")@RequestBody LoginForm loginForm, @ApiParam("请求request对象")HttpServletRequest request){
        //验证码校验
        HttpSession session = request.getSession();
        String verifiCode = (String) session.getAttribute("verifiCode");
        String verifiCode1 = loginForm.getVerifiCode();
        if("".equals(verifiCode) || null == verifiCode){
            return Result.fail().message("验证码失效，请刷新后重试！") ;
        }
        if(!verifiCode.equalsIgnoreCase(verifiCode1)){
            return Result.fail().message("验证码有误，请刷新后重试！") ;
        }
//        从sessiion域移除验证码
        session.removeAttribute("verifiCode");
        //        分用户类型进行校验
        //准备map存储响应数据
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        switch (loginForm.getUserType()){
            case 1:
                try{
                    Admin admin = adminService.login(loginForm);
                    if(null != admin){
                        //用户类型和id转密文传给客户端
                        String token = JwtHelper.createToken(admin.getId().longValue(), 1);
                        map.put("token",token) ;
                    }else {
                        throw new RuntimeException("用户名或密码错误");
                    }
                    return Result.ok(map) ;
                }catch (Exception e){
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
            case 2:
                try{
                    Student student = studentService.login(loginForm);
                    if(null != student){
                        //用户类型和id转密文传给客户端
                        String token = JwtHelper.createToken(student.getId().longValue(), 2);
                        map.put("token",token) ;
                    }else {
                        throw new RuntimeException("用户名或密码错误");
                    }
                    return Result.ok(map) ;
                }catch (Exception e){
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
            case 3:
                try{
                    Teacher teacher = teacherService.login(loginForm);
                    if(null != teacher){
                        //用户类型和id转密文传给客户端
                        String token = JwtHelper.createToken(teacher.getId().longValue(), 3);
                        map.put("token",token) ;
                    }else {
                        throw new RuntimeException("用户名或密码错误");
                    }
                    return Result.ok(map) ;
                }catch (Exception e){
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
        }
        return Result.fail().message("查无此用户");
    }


    @ApiOperation("获取验证码")
    @GetMapping("/getVerifiCodeImage")
    public void getVerifiCodeImage(@ApiParam("请求对象")HttpServletRequest request, @ApiParam("响应对象")HttpServletResponse response){
//        获取图片
        BufferedImage verifiCodeImage = CreateVerifiCodeImage.getVerifiCodeImage();
//        获取验证码
        String verifiCode = String.valueOf(CreateVerifiCodeImage.getVerifiCode());
//        将验证码文本放入session域，为下一次做准备
        HttpSession session = request.getSession();
        session.setAttribute("verifiCode",verifiCode);
//        将验证码图片响应给浏览器
        try{
            ServletOutputStream outputStream = response.getOutputStream();
            ImageIO.write(verifiCodeImage, "JPEG", outputStream);
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    @ApiOperation("更新用户密码的处理器")
    @PostMapping("/updatePwd/{orignPassword}/{newPassword}")
    public Result updatePwd(
            @ApiParam("旧密码")@PathVariable("orignPassword") String orignPassword,
            @ApiParam("新密码")@PathVariable("newPassword") String newPassword,
            @ApiParam("Token口令") @RequestHeader  String token
    ){
//        检查touken是否过期
        boolean expiration = JwtHelper.isExpiration(token);
        if(expiration){
            //token过期
            return Result.fail().message("token失效，请重新登录后修改密码");
        }
        Integer userType = JwtHelper.getUserType(token);
        Long userId = JwtHelper.getUserId(token);
        String oldPwd = MD5.encrypt(orignPassword);
        String newPwd = MD5.encrypt(newPassword);
        switch (userType){
            case 1:
                QueryWrapper<Admin> queryWrapper = new QueryWrapper<>() ;
                queryWrapper.eq("id",userId) ;
                queryWrapper.eq("password",oldPwd);
                Admin admin = adminService.getOne(queryWrapper);
                if(admin!=null){
                    admin.setPassword(newPwd);
                    adminService.saveOrUpdate(admin) ;
                }else{
                    return Result.fail().message("原密码有误");
                }
                break;
            case 2:
                QueryWrapper<Student> queryWrapper1 = new QueryWrapper<>() ;
                queryWrapper1.eq("id",userId) ;
                queryWrapper1.eq("password",oldPwd);
                Student student = studentService.getOne(queryWrapper1);
                if(student!=null){
                    student.setPassword(newPwd);
                    studentService.saveOrUpdate(student) ;
                }else{
                    return Result.fail().message("原密码有误");
                }
                break;
            case 3:
                QueryWrapper<Teacher> queryWrapper2 = new QueryWrapper<>() ;
                queryWrapper2.eq("id",userId) ;
                queryWrapper2.eq("password",oldPwd);
                Teacher teacher = teacherService.getOne(queryWrapper2);
                if(teacher!=null){
                    teacher.setPassword(newPwd);
                    teacherService.saveOrUpdate(teacher) ;
                }else{
                    return Result.fail().message("原密码有误");
                }
                break;
        }
        return Result.ok() ;
    }
}
